﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace PloobsEngine.Modelo
{
    public class ModelBuilderHelper
    {
        public static void Extract(Model model,out BatchInformation[][] batchInformationS,out VertexBuffer[] vertexBufferS,out IndexBuffer[] indexBufferS)
        {
            indexBufferS = new IndexBuffer[model.Meshes.Count];
            vertexBufferS = new VertexBuffer[model.Meshes.Count];
            batchInformationS = new BatchInformation[model.Meshes.Count][];
            for (int j = 0; j < model.Meshes.Count; j++)
            {
                ModelMesh mesh = model.Meshes[j];
                indexBufferS[j] = mesh.IndexBuffer;
                vertexBufferS[j] = mesh.VertexBuffer;
                
                BatchInformation[] b = new BatchInformation[mesh.MeshParts.Count];
                for (int i = 0; i < mesh.MeshParts.Count; i++)
                {
                    b[i] = new BatchInformation(mesh.MeshParts[i].BaseVertex, mesh.MeshParts[i].NumVertices, mesh.MeshParts[i].PrimitiveCount, mesh.MeshParts[i].StartIndex, mesh.MeshParts[i].StreamOffset, mesh.MeshParts[i].VertexDeclaration, mesh.MeshParts[i].VertexStride);
                }

                batchInformationS[j] = b;
            }
        }
        public static void Extract(ModelMesh mesh, out BatchInformation[][] batchInformationS, out VertexBuffer[] vertexBufferS, out IndexBuffer[] indexBufferS)
        {
            indexBufferS = new IndexBuffer[1];
            vertexBufferS = new VertexBuffer[1];
            batchInformationS = new BatchInformation[1][];            
                            
                indexBufferS[0] = mesh.IndexBuffer;
                vertexBufferS[0] = mesh.VertexBuffer;

                BatchInformation[] b = new BatchInformation[mesh.MeshParts.Count];
                for (int i = 0; i < mesh.MeshParts.Count; i++)
                {
                    b[i] = new BatchInformation(mesh.MeshParts[i].BaseVertex, mesh.MeshParts[i].NumVertices, mesh.MeshParts[i].PrimitiveCount, mesh.MeshParts[i].StartIndex, mesh.MeshParts[i].StreamOffset, mesh.MeshParts[i].VertexDeclaration, mesh.MeshParts[i].VertexStride);
                }

                batchInformationS[0] = b;
        }


        public static BoundingBox GetModelBB(Model model, bool bTransformed)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);
            Matrix matTransform;

            Vector3 Max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            Vector3 Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            foreach (ModelMesh mesh in model.Meshes)
            {
                matTransform = transforms[mesh.ParentBone.Index];

                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int stride = part.VertexStride;
                    int numberv = part.NumVertices;
                    //VertexDeclaration test1 = part.VertexDeclaration;      // not used for now
                    byte[] data = new byte[stride * numberv];

                    System.Diagnostics.Debug.WriteLine("stride=" + stride.ToString() +
                                                       "numv  =" + numberv.ToString());

                    mesh.VertexBuffer.GetData<byte>(data);

                    for (int ndx = 0; ndx < data.Length; ndx += stride)
                    {
                        float floatvaluex = BitConverter.ToSingle(data, ndx);
                        float floatvaluey = BitConverter.ToSingle(data, ndx + 4);
                        float floatvaluez = BitConverter.ToSingle(data, ndx + 8);
                        Vector3 vectCurrentVertex = new Vector3(floatvaluex, floatvaluey, floatvaluez);
                        Vector3 vectWorldVertex = Vector3.Transform(vectCurrentVertex, matTransform);

                        if (bTransformed)
                        {
                            if (vectWorldVertex.X < Min.X) Min.X = vectWorldVertex.X;
                            if (vectWorldVertex.X > Max.X) Max.X = vectWorldVertex.X;
                            if (vectWorldVertex.Y < Min.Y) Min.Y = vectWorldVertex.Y;
                            if (vectWorldVertex.Y > Max.Y) Max.Y = vectWorldVertex.Y;
                            if (vectWorldVertex.Z < Min.Z) Min.Z = vectWorldVertex.Z;
                            if (vectWorldVertex.Z > Max.Z) Max.Z = vectWorldVertex.Z;
                        }
                        else
                        {
                            if (floatvaluex < Min.X) Min.X = floatvaluex;
                            if (floatvaluex > Max.X) Max.X = floatvaluex;
                            if (floatvaluey < Min.Y) Min.Y = floatvaluey;
                            if (floatvaluey > Max.Y) Max.Y = floatvaluey;
                            if (floatvaluez < Min.Z) Min.Z = floatvaluez;
                            if (floatvaluez > Max.Z) Max.Z = floatvaluez;
                        }
                    }
                }
            }
            System.Diagnostics.Debug.WriteLine(" Min=" + Min.ToString());
            System.Diagnostics.Debug.WriteLine(" Max=" + Max.ToString());
            BoundingBox boundingbox = new BoundingBox(Min, Max);  // presto  
            return boundingbox;
        }  

    }


}
